<template>
  <!-- 实名认证组件的结构 -->
  <el-card class="box-card">
    <!-- 卡片头部 -->
    <template #header>
      <div class="card-header">
        <h1>实名信息</h1>
      </div>
    </template>
    <!-- 卡片身体：提示部分 -->
    <div class="tip" style="color: #7f7f7f;">
      <p><el-icon>
          <InfoFilled />
        </el-icon>完成实名认证后才能添加就诊人，正常进行挂号，为了不影响后续步骤，建议提前实名认证。</p>
    </div>
    <!-- 卡片身体：认证成功 -->
    <el-descriptions v-if="userInfo.authStatus" size="small" class="margin-top" :column="1" border
      style="margin: 20px auto;">
      <el-descriptions-item :width="20" label-align="center">
        <template #label>
          <div class="cell-item">
            用户姓名
          </div>
        </template>
        {{ userInfo.name }}
      </el-descriptions-item>
      <el-descriptions-item :width="20" label-align="center">
        <template #label>
          <div class="cell-item">
            证件类型
          </div>
        </template>
        {{ userInfo.certificatesType == '10' ? '身份证' : '户口本' }}
      </el-descriptions-item>
      <el-descriptions-item :width="20" label-align="center">
        <template #label>
          <div class="cell-item">
            证件号码
          </div>
        </template>
        {{ userInfo.certificatesNo }}
      </el-descriptions-item>
    </el-descriptions>
    <!-- 卡片身体：用户未认证 -->
    <el-form v-else style="width: 60%; margin: 20px auto;" label-width="80" :model="params" :rules="rules" ref="form">
      <el-form-item label="用户姓名" prop="name">
        <el-input placeholder="请输入用户姓名" v-model="params.name"></el-input>
      </el-form-item>
      <el-form-item label="证件类型" prop="certificatesType">
        <el-select style="width: 100%;" placeholder="请选择证件类型" v-model="params.certificatesType">
          <el-option :label="item.name" :value="item.value" v-for="(item, index) in certationType"
            :key="index"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="证件号码" prop="certificatesNo">
        <el-input placeholder="请输入证件号码" v-modal="params.certificatesNo"></el-input>
      </el-form-item>
      <el-form-item label="上传证件" prop="certificatesUrl">
        <el-upload ref="upload" list-type="picture-card" action="/api/oss/file/fileUpload?fileHost=userAuah" :limit="1"
          :on-exceed="exceedhandler" :on-success="successhandler" :on-preview="handlePictureCardPreview"
          :on-remove="handleRemove">
          <img style="width: 100%; height: 100%;" src="../../../assets/images/auth_example.png" alt="">
        </el-upload>
        <el-dialog v-model="dialogVisible">
          <img w-full alt="Preview Image" v-if="params.certificatesUrl" :src="params.certificatesUrl"
            style="width: 100%;height: 100%;" />
        </el-dialog>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" size="default" @click="submit">提交</el-button>
        <el-button size="default" @click="reset">重写</el-button>
      </el-form-item>
    </el-form>
  </el-card>
</template>

<script setup lang="ts" name="Certification">
//引入图标
import {
  InfoFilled,
} from '@element-plus/icons-vue'
//引入响应式API
import { ref, reactive, onMounted } from 'vue'
//引入请求用户信息的请求方法和ts类型
//@ts-ignore
import { reqUserInfo, reqCertationType, reqUserCertation } from '@/api/user'
//@ts-ignore
import type { UserInfoResponseData, UserInfo, CertationTypeResponseData, CertationArr, UserParams } from '@/api/user/type'
//引入消息提示
import { ElMessage } from 'element-plus'

//用户信息数据
let userInfo = ref<UserInfo>({} as UserInfo)
//认证类型数据
let certationType = ref<CertationArr>([] as CertationArr)
//用户表单认证的数据
let params = reactive<UserParams>({
  certificatesType: '',
  certificatesUrl: '',
  certificatesNo: '',
  name: '',
})
//对话框的显示和隐藏
let dialogVisible = ref<boolean>(false)
//获取组件实例
let upload = ref()
//获取表单元素
let form = ref()

//发送请求获取用户信息
const getUserInfo = async () => {
  let result: UserInfoResponseData = await reqUserInfo()
  if (result.code == 200) {
    //获取用户信息数据
    userInfo.value = result.data
  }
}
//发送请求获取证件类型数据
const getCertationType = async () => {
  let result: CertationTypeResponseData = await reqCertationType()
  if (result.code == 200) {
    certationType.value = result.data
  }
}
//组件挂载：发送请求，获取数据
onMounted(() => {
  //发送请求获取用户信息数据
  getUserInfo()
  //发送请求获取证件类型数据
  getCertationType()
})
//图片上传超过1张的钩子
const exceedhandler = () => {
  ElMessage({
    type: 'error',
    message: '只能上传一张图片'
  })
}
//图片上传成功的钩子
const successhandler = (response: any) => {
  //如果图片上传成功，校验结果清除
  form.value.clearValidate('certificatesUrl')
  //获取上传图片的url
  params.certificatesUrl = response.data
}
//预览图片的钩子
const handlePictureCardPreview = () => {
  //对话框显示
  dialogVisible.value = true
}
//删除图片的钩子
const handleRemove = () => {
  params.certificatesUrl = ''
}
//重写按钮的回调
const reset = () => {
  //清除用户表单验证的数据
  Object.assign(params, {
    certificatesType: '',
    certificatesUrl: '',
    certificatesNo: '',
    name: '',
  })
  //清除文件列表
  upload.value.clearFiles()
}
//点击提交的回调
const submit = async () => {
  //全部的表单校验（await的用途，等所有的表单项校验通过才会往下执行，发送请求存储用户表单验证数据）
  await form.value.validate()
  //发送请求，存储用户表单验证数据
  try {
    //认证成功
    await reqUserCertation(params)
    //成功的提示
    ElMessage({
      type: 'success',
      message: '认证成功',
    })
    //发送请求获取用户信息数据
    getUserInfo()
  } catch (error) {
    //失败的提示
    ElMessage({
      type: 'error',
      message: '认证失败',
    })
  }
}
//表单校验
//@ts-ignore
const validatorName = (rule: any, value: any, callback: any) => {
  let reg = /^[\u4e00-\u9fa5]{2,4}$/
  if (reg.test(value)) {
    callback()
  } else {
    callback(new Error('请输入正确的中国人的名字'))
  }
}
//@ts-ignore
const validatorCertificatesType = (rule: any, value: any, callback: any) => {
  if (value == '10' || value == '20') {
    callback()
  } else {
    callback(new Error('请选择证件的类型'))
  }
}
//@ts-ignore
const validatorCertificatesNo = (rule: any, value: any, callback: any) => {
  let sfz = /^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/
  let hkb = /^\d{9}$/
  if (sfz.test(value) || hkb.test(value)) {
    callback()
  } else {
    callback(new Error('请输入正确的身份证或户口本号码'))
  }
}
//@ts-ignore
const validatorCertificatesUrl = (rule: any, value: any, callback: any) => {
  if (value.length) {
    callback()
  } else {
    callback(new Error('请上传证件照图片'))
  }
}
const rules = {
  name: [{
    required: true,
    validator: validatorName
  }],
  certificatesType: [{
    required: true,
    validator: validatorCertificatesType
  }],
  certificatesNo: [{
    required: true,
    validator: validatorCertificatesNo
  }],
  certificatesUrl: [{
    required: true,
    validator: validatorCertificatesUrl
  }]
}
</script>

<style scoped lang="scss">
.box-card {
  .tip {
    display: flex;
    justify-content: center;
    align-items: center;
  }
}
</style>